package primitive3D;

import java.util.ArrayList;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import rayTracer.AABB;
import rayTracer.Ray;
import rayTracer.Transformation;

public class GenericMesh extends Primitive3D {
	private Primitive3D intersected;
	
	public GenericMesh(ArrayList<Primitive3D> elements, Point3d bbMin, Point3d bbMax){
		components = elements;		
		bb = new AABB(new Point3d(bbMin), new Point3d(bbMax) );
		name = new String("");
	}
	
	/*
	public int intersects(Ray ray, Point3d[] pts) throws Exception {
		Set<Point3d> ptsAux = new HashSet<Point3d>();
		for( Primitive3D aPrimitive : components ) {		
			if( aPrimitive.intersects(ray, pts) == 1 ) {
				ptsAux.add( new Point3d(pts[0]) );
			}
		}
		
		Iterator<Point3d> it = ptsAux.iterator();

		int cantIntersections = 0;
		if( it.hasNext() ) {
			pts[0] = it.next();
			cantIntersections++;
		}
		while( it.hasNext()) {
			Point3d p = it.next();
			if( !p.epsilonEquals(pts[0], 0.001) ) {				
				pts[1] = p;
				cantIntersections++;
				break;
			}
		}
		return cantIntersections;
	}
*/
	@Override
	// Devuelve la distancia al punto intersectado en el nombre de
	// la funcion. Si no hay interseccion devuelve -1.  
	public double intersects(Ray ray) {
		double distance, minDistance = Double.POSITIVE_INFINITY;	
		for( Primitive3D aPrimitive : components ) {
			distance = aPrimitive.intersects(ray);
			if( 0 <= distance && distance < minDistance ) {				
				minDistance = distance;
				this.intersected = aPrimitive;
			}
		}
		if( minDistance == Double.POSITIVE_INFINITY ) minDistance = -1;
		return minDistance;
	}
	
	// Devuelve un vector normal a la superficie del mesh que pasa por p
	// p debe ser un punto de la superficie del mesh
	public Vector3d getNormal(Point3d p) {
		// Uso el triangulo que fue intersectado por el rayo anteriormente.
		return this.intersected.getNormal(p);
	}
	
	@Override
	public void scaleFromReferencePosition(Point3d referencePosition,
			double scaleFactor) {
		// TODO Auto-generated method stub

	}

	@Override
	public void setPosition(Point3d otherPosition) {
		// TODO Auto-generated method stub

	}

	@Override
	public String toString() {
		StringBuffer str = new StringBuffer();
		
		str.append("Generic-Mesh \"" + getName() + "\""+"cantTriangles="+components.size()+"  bb.min="+bb.min+"bb.max="+bb.max);
		for( int i=0 ; i<components.size(); i++ ){
			components.get(i).name = String.valueOf(i*10);
			str.append(components.get(i)+"\n");
		}
		return str.toString();
	}
	@Override
	public int transform(Transformation trans) {
		for( Primitive3D p : components )
			p.transform(trans);
		return 0;
	}

}
